//
//  GWWaterFllowView.m
//  瀑布流
//
//  Created by qianfeng on 16/2/29.
//  Copyright (c) 2016年 高炜. All rights reserved.
//

#import "GWWaterFllowView.h"
#import "GWWaterFllowViewCell.h"
#define GWWaterFllowViewDefaultCellHeight 70
#define GWWaterFllowViewDefaultClumns 3
#define GWWaterFllowViewDefaultMargin 8

@interface GWWaterFllowView ()
@property (nonatomic,strong)NSMutableArray *cellRects;
@property (nonatomic,strong)NSMutableDictionary *inScreenCells;

@property (nonatomic,strong)NSMutableSet *reuseableCells;
@end
@implementation GWWaterFllowView
-(NSMutableSet *)reuseableCells
{
    if (_reuseableCells==nil) {
        _reuseableCells =[NSMutableSet set];
    }
    return _reuseableCells;
}
-(NSMutableDictionary *)inScreenCells
{
    if (_inScreenCells==nil) {
        _inScreenCells =[NSMutableDictionary dictionary];
    }
    return _inScreenCells;
}
-(NSMutableArray *)cellRects
{
    if (_cellRects==nil) {
        _cellRects =[NSMutableArray array];
    }
    return _cellRects;
}


-(void)willMoveToSuperview:(UIView *)newSuperview
{
    [self reloadData];
}

- (id)dequeueReusableCellWithIdentifier:(NSString *)identifier
{
   __block GWWaterFllowViewCell *reuseCell =nil;
    [self.reuseableCells enumerateObjectsUsingBlock:^(GWWaterFllowViewCell *cell, BOOL *stop) {
        if ([cell.identifier isEqualToString:identifier]) {
            reuseCell =cell;
            
            *stop =YES;
        }
    }];
    if (reuseCell) {
        [self.reuseableCells removeObject:reuseCell];
    }
    
    return reuseCell;
}
-(void)layoutSubviews
{
    [super layoutSubviews];
    NSInteger cellCount =self.cellRects.count;
    
    for (int i=0; i<cellCount; i++) {
        CGRect cellFram =[self.cellRects[i] CGRectValue];
        GWWaterFllowViewCell *cell = self.inScreenCells[@(i)];
        if ([self isInScreen:cellFram]) {
            
            if (cell==nil) {
              cell =  [self.dataSource waterFllowView:self cellForRowAtIndex:i];
            }
            cell.frame =cellFram;
            [self addSubview:cell];
            self.inScreenCells[@(i)] =cell;
        }
        else
        {
            if (cell) {
                [cell removeFromSuperview];
                [self.inScreenCells removeObjectForKey:@(i)];
                
                [self.reuseableCells addObject:cell];
            }
            
        }
    }
}
-(BOOL)isInScreen:(CGRect)cellFram
{
    return (CGRectGetMaxY(cellFram)>self.contentOffset.y && CGRectGetMinY(cellFram)<(self.contentOffset.y+self.height));
}
-(CGFloat)cellWidth
{
    CGFloat marginLeft = [self marginWithType:GWWaterFllowViewMarginTypeLeft];
    CGFloat marginRight = [self marginWithType:GWWaterFllowViewMarginTypeRight];
     int clumns = (int)[self clumns];
    CGFloat marginClumns = [self marginWithType:GWWaterFllowViewMarginTypeClumns];
    
    return (self.width -marginLeft-marginRight-(clumns-1)*marginClumns)/clumns;
}
-(void)reloadData
{
    [self.inScreenCells.allValues makeObjectsPerformSelector:@selector(removeFromSuperview)];
    [self.inScreenCells removeAllObjects];
    [self.cellRects removeAllObjects];
    [self.reuseableCells removeAllObjects];
    
    CGFloat cellCount =[self.dataSource numberOfCellsInWaterFllowView:self];
    int clumns = (int)[self clumns];
    CGFloat marginLeft = [self marginWithType:GWWaterFllowViewMarginTypeLeft];
//    CGFloat marginRight = [self marginWithType:GWWaterFllowViewMarginTypeRight];
    CGFloat marginTop = [self marginWithType:GWWaterFllowViewMarginTypeTop];
    CGFloat marginBottom = [self marginWithType:GWWaterFllowViewMarginTypeBottom];
    CGFloat marginClumns = [self marginWithType:GWWaterFllowViewMarginTypeClumns];
    CGFloat marginRow = [self marginWithType:GWWaterFllowViewMarginTypeRow];
    
    CGFloat cellW = self.cellWidth;
    
    CGFloat maxYofClumns[clumns];
    for (int i=0; i<clumns; i++) {
        maxYofClumns[i]=0.0;
    }
    
    for (int i=0; i<cellCount; i++) {
        CGFloat cellH =[self cellHeightWihtIndex:i];
        NSInteger miniCellClumns =0;
        CGFloat miniY =maxYofClumns[miniCellClumns];
        
        for (int j=1; j<clumns; j++) {
            if (maxYofClumns[j]<miniY) {
                miniCellClumns =j;
                miniY =maxYofClumns[j];
            }
        }
        
        CGFloat cellX = marginLeft +miniCellClumns*(cellW+marginClumns);
        CGFloat cellY =0;
        if (miniY==0.0) {
            cellY = marginTop;
        }else
        {
            cellY = miniY + marginRow;
        }
        CGRect cellRect =CGRectMake(cellX, cellY, cellW, cellH);
        
        [self.cellRects addObject:[NSValue valueWithCGRect:cellRect]];
        
        maxYofClumns[miniCellClumns] =CGRectGetMaxY(cellRect);
    }
    
    NSInteger maxCellClumns =0;
    CGFloat maxY =maxYofClumns[maxCellClumns];
    
    for (int j=1; j<clumns; j++) {
        if (maxYofClumns[j]>maxY) {
            maxCellClumns =j;
            maxY =maxYofClumns[j];
        }
    }
    self.contentSize =CGSizeMake(0, maxY+marginBottom);
}
-(CGFloat)marginWithType:(GWWaterFllowViewMarginType)marginType
{
    if ([self.delegate respondsToSelector:@selector(waterFllowView:marginWithType:)]) {
       return [self.delegate waterFllowView:self marginWithType:marginType];
    }
    else
    {
        return GWWaterFllowViewDefaultMargin;
    }
}
-(NSInteger)clumns
{
    if ([self.dataSource respondsToSelector:@selector(numberOfclumnsInWaterFllowView:)]) {
        return [self.dataSource numberOfclumnsInWaterFllowView:self];
    }
    else
    {
        return GWWaterFllowViewDefaultClumns;
    }
    
}
-(CGFloat)cellHeightWihtIndex:(NSInteger)index
{
    if ([self.dataSource respondsToSelector:@selector(waterFllowView:heightForCellAtIndex:)]) {
        return [self.delegate waterFllowView:self heightForCellAtIndex:index];
    }
    else
    {
        return GWWaterFllowViewDefaultCellHeight;
    }
}

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    if (![self.delegate respondsToSelector:@selector(waterFllowView:didSelectCellAtIndex:)])return;
    UITouch *touch =[touches anyObject];
    CGPoint point = [touch locationInView:self];
    __block NSNumber *selectedIndex =nil;
    [self.inScreenCells enumerateKeysAndObjectsUsingBlock:^(id key, GWWaterFllowViewCell *cell, BOOL *stop) {
        if (CGRectContainsPoint(cell.frame, point)) {
            selectedIndex =key;
            *stop =YES;
        }
    }];
    if (selectedIndex) {
        [self.delegate waterFllowView:self didSelectCellAtIndex:[selectedIndex unsignedIntegerValue]];
    }
}
@end
